home *** CD-ROM | disk | FTP | other *** search
/ Mac Easy 2010 May / Mac Life Ubuntu.iso / casper / filesystem.squashfs / usr / lib / gedit-2 / plugins / snippets / Snippet.py < prev    next >
Encoding:
Python Source  |  2009-04-14  |  15.0 KB  |  356 lines

  1. #    Gedit snippets plugin
  2. #    Copyright (C) 2005-2006  Jesse van den Kieboom <jesse@icecrew.nl>
  3. #
  4. #    This program is free software; you can redistribute it and/or modify
  5. #    it under the terms of the GNU General Public License as published by
  6. #    the Free Software Foundation; either version 2 of the License, or
  7. #    (at your option) any later version.
  8. #
  9. #    This program is distributed in the hope that it will be useful,
  10. #    but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. #    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12. #    GNU General Public License for more details.
  13. #
  14. #    You should have received a copy of the GNU General Public License
  15. #    along with this program; if not, write to the Free Software
  16. #    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  17.  
  18. import os
  19. import gio
  20.  
  21. from Placeholder import *
  22. from Parser import Parser, Token
  23. from Helper import *
  24.  
  25. class EvalUtilities:
  26.         def __init__(self, view=None):
  27.                 self.view = view
  28.                 self._init_namespace()
  29.         
  30.         def _init_namespace(self):
  31.                 self.namespace = {
  32.                         '__builtins__': __builtins__,
  33.                         'align': self.util_align,
  34.                         'readfile': self.util_readfile,
  35.                         'filesize': self.util_filesize
  36.                 }
  37.  
  38.         def _real_len(self, s, tablen = 0):
  39.                 if tablen == 0:
  40.                         tablen = self.view.get_tab_width()
  41.  
  42.                 return len(s.expandtabs(tablen))
  43.  
  44.         def _filename_to_uri(self, filename):
  45.                 gfile = gio.File(filename)
  46.  
  47.                 return gfile.get_uri()
  48.  
  49.         def util_readfile(self, filename):
  50.                 stream = gio.File(filename).read()
  51.                 
  52.                 if not stream:
  53.                         return ''
  54.                 
  55.                 res = stream.read()
  56.                 stream.close()
  57.                 
  58.                 return res
  59.  
  60.         def util_filesize(self, filename):
  61.                 gfile = gio.File(filename)
  62.                 info = gfile.query_info(gio.FILE_ATTRIBUTE_STANDARD_SIZE)
  63.                 
  64.                 if not info:
  65.                         return 0
  66.                 
  67.                 return info.get_size()
  68.  
  69.         def util_align(self, items):
  70.                 maxlen = []
  71.                 tablen = self.view.get_tab_width()
  72.  
  73.                 for row in range(0, len(items)):
  74.                         for col in range(0, len(items[row]) - 1):
  75.                                 if row == 0:
  76.                                         maxlen.append(0)
  77.                                 
  78.                                 items[row][col] += "\t"
  79.                                 rl = self._real_len(items[row][col], tablen)
  80.                                 
  81.                                 if (rl > maxlen[col]):
  82.                                         maxlen[col] = rl
  83.  
  84.                 result = ''
  85.                 
  86.                 for row in range(0, len(items)):
  87.                         for col in range(0, len(items[row]) - 1):
  88.                                 item = items[row][col]
  89.                                 
  90.                                 result += item + ("\t" * ((maxlen[col] - \
  91.                                                 self._real_len(item, tablen)) / tablen))
  92.                         
  93.                         result += items[row][len(items[row]) - 1]
  94.                         
  95.                         if row != len(items) - 1:
  96.                                 result += "\n"
  97.                 
  98.                 return result
  99.  
  100. class Snippet:
  101.         def __init__(self, data):
  102.                 self.data = data
  103.         
  104.         def __getitem__(self, prop):
  105.                 return self.data[prop]
  106.         
  107.         def __setitem__(self, prop, value):
  108.                 self.data[prop] = value
  109.         
  110.         def accelerator_display(self):
  111.                 accel = self['accelerator']
  112.  
  113.                 if accel:
  114.                         keyval, mod = gtk.accelerator_parse(accel)
  115.                         accel = gtk.accelerator_get_label(keyval, mod)
  116.                 
  117.                 return accel or ''
  118.  
  119.         def display(self):
  120.                 nm = markup_escape(self['description'])
  121.                 
  122.                 tag = self['tag']
  123.                 accel = self.accelerator_display()
  124.                 detail = []
  125.                 
  126.                 if tag and tag != '':
  127.                         detail.append(tag)
  128.                         
  129.                 if accel and accel != '':
  130.                         detail.append(accel)
  131.                 
  132.                 if not detail:
  133.                         return nm
  134.                 else:
  135.                         return nm + ' (<b>' + markup_escape(str.join(', ', detail)) + \
  136.                                         '</b>)'
  137.  
  138.         def _add_placeholder(self, placeholder):
  139.                 if placeholder.tabstop in self.placeholders:
  140.                         if placeholder.tabstop == -1:
  141.                                 self.placeholders[-1].append(placeholder)
  142.                                 self.plugin_data.ordered_placeholders.append(placeholder)
  143.                 elif placeholder.tabstop == -1:
  144.                         self.placeholders[-1] = [placeholder]
  145.                         self.plugin_data.ordered_placeholders.append(placeholder)
  146.                 else:
  147.                         self.placeholders[placeholder.tabstop] = placeholder
  148.                         self.plugin_data.ordered_placeholders.append(placeholder)
  149.  
  150.         def _insert_text(self, text):
  151.                 # Insert text keeping indentation in mind
  152.                 indented = unicode.join('\n' + unicode(self._indent), spaces_instead_of_tabs(self._view, text).split('\n'))
  153.                 self._view.get_buffer().insert(self._insert_iter(), indented)
  154.  
  155.         def _insert_iter(self):
  156.                 return self._view.get_buffer().get_iter_at_mark(self._insert_mark)
  157.                 
  158.         def _create_environment(self, data):
  159.                 val = ((data in os.environ) and os.environ[data]) or ''
  160.                 
  161.                 # Get all the current indentation
  162.                 all_indent = compute_indentation(self._view, self._insert_iter())
  163.                 
  164.                 # Substract initial indentation to get the snippet indentation
  165.                 indent = all_indent[len(self._indent):]
  166.  
  167.                 # Keep indentation
  168.                 return unicode.join('\n' + unicode(indent), val.split('\n'))
  169.         
  170.         def _create_placeholder(self, data):
  171.                 tabstop = data['tabstop']
  172.                 begin = self._insert_iter()
  173.                 
  174.                 if tabstop == 0:
  175.                         # End placeholder
  176.                         return PlaceholderEnd(self._view, begin, data['default'])
  177.                 elif tabstop in self.placeholders:
  178.                         # Mirror placeholder
  179.                         return PlaceholderMirror(self._view, tabstop, begin)
  180.                 else:
  181.                         # Default placeholder
  182.                         return Placeholder(self._view, tabstop, data['default'], begin)
  183.  
  184.         def _create_shell(self, data):
  185.                 begin = self._insert_iter()
  186.                 return PlaceholderShell(self._view, data['tabstop'], begin, data['contents'])
  187.  
  188.         def _create_eval(self, data):
  189.                 begin = self._insert_iter()
  190.                 return PlaceholderEval(self._view, data['tabstop'], data['dependencies'], begin, data['contents'], self._utils.namespace)
  191.         
  192.         def _create_regex(self, data):
  193.                 begin = self._insert_iter()
  194.                 return PlaceholderRegex(self._view, data['tabstop'], begin, data['input'], data['pattern'], data['substitution'], data['modifiers'])
  195.                 
  196.         def _create_text(self, data):
  197.                 return data
  198.  
  199.         def _invalid_placeholder(self, placeholder, remove):
  200.                 buf = self._view.get_buffer()
  201.               
  202.                 # Remove the text because this placeholder is invalid
  203.                 if placeholder.default and remove:
  204.                         buf.delete(placeholder.begin_iter(), placeholder.end_iter())
  205.                 
  206.                 placeholder.remove()
  207.  
  208.                 if placeholder.tabstop == -1:
  209.                         index = self.placeholders[-1].index(placeholder)
  210.                         del self.placeholders[-1][index]
  211.                 else:
  212.                         del self.placeholders[placeholder.tabstop]
  213.                 
  214.                 self.plugin_data.ordered_placeholders.remove(placeholder)
  215.  
  216.         def _parse(self, plugin_data):
  217.                 # Initialize current variables
  218.                 self._view = plugin_data.view
  219.                 self._indent = compute_indentation(self._view, self._view.get_buffer().get_iter_at_mark(self.begin_mark))        
  220.                 self._utils = EvalUtilities(self._view)
  221.                 self.placeholders = {}
  222.                 self._insert_mark = self.end_mark
  223.                 self.plugin_data = plugin_data
  224.                 
  225.                 # Create parser
  226.                 parser = Parser(data=self['text'])
  227.  
  228.                 # Parse tokens
  229.                 while (True):
  230.                         token = parser.token()
  231.                         
  232.                         if not token:
  233.                                 break
  234.  
  235.                         try:
  236.                                 val = {'environment': self._create_environment,
  237.                                         'placeholder': self._create_placeholder,
  238.                                         'shell': self._create_shell,
  239.                                         'eval': self._create_eval,
  240.                                         'regex': self._create_regex,
  241.                                         'text': self._create_text}[token.klass](token.data)
  242.                         except:
  243.                                 sys.stderr.write('Token class not supported: %s\n' % token.klass)
  244.                                 continue
  245.                         
  246.                         if isinstance(val, basestring):
  247.                                 # Insert text
  248.                                 self._insert_text(val)
  249.                         else:
  250.                                 # Insert placeholder
  251.                                 self._add_placeholder(val)
  252.  
  253.                 # Create end placeholder if there isn't one yet
  254.                 if 0 not in self.placeholders:
  255.                         self.placeholders[0] = PlaceholderEnd(self._view, self.end_iter(), None)
  256.                         self.plugin_data.ordered_placeholders.append(self.placeholders[0])
  257.  
  258.                 # Make sure run_last is ran for all placeholders and remove any
  259.                 # non `ok` placeholders
  260.                 for tabstop in self.placeholders.copy():
  261.                         ph = (tabstop == -1 and list(self.placeholders[-1])) or [self.placeholders[tabstop]]
  262.  
  263.                         for placeholder in ph:
  264.                                 placeholder.run_last(self.placeholders)
  265.                                 
  266.                                 if not placeholder.ok or placeholder.done:
  267.                                         self._invalid_placeholder(placeholder, not placeholder.ok)
  268.  
  269.                 # Remove all the Expand placeholders which have a tabstop because
  270.                 # they can be used to mirror, but they shouldn't be real tabstops
  271.                 # (if they have mirrors installed). This is problably a bit of 
  272.                 # a dirty hack :)
  273.                 if -1 not in self.placeholders:
  274.                         self.placeholders[-1] = []
  275.  
  276.                 for tabstop in self.placeholders.copy():
  277.                         placeholder = self.placeholders[tabstop]
  278.  
  279.                         if tabstop != -1:
  280.                                 if isinstance(placeholder, PlaceholderExpand) and \
  281.                                    placeholder.has_references:
  282.                                         # Add to anonymous placeholders
  283.                                         self.placeholders[-1].append(placeholder)
  284.                                         
  285.                                         # Remove placeholder
  286.                                         del self.placeholders[tabstop]
  287.         
  288.                 self.plugin_data = None
  289.  
  290.         def insert_into(self, plugin_data, insert):
  291.                 buf = plugin_data.view.get_buffer()
  292.                 last_index = 0
  293.                 
  294.                 # Find closest mark at current insertion, so that we may insert
  295.                 # our marks in the correct order
  296.                 (current, next) = plugin_data.next_placeholder()
  297.                 
  298.                 if current:
  299.                         # Insert AFTER current
  300.                         last_index = plugin_data.placeholders.index(current) + 1
  301.                 elif next:
  302.                         # Insert BEFORE next
  303.                         last_index = plugin_data.placeholders.index(next)
  304.                 else:
  305.                         # Insert at first position
  306.                         last_index = 0
  307.                 
  308.                 # lastIndex now contains the position of the last mark
  309.                 # Create snippet bounding marks
  310.                 self.begin_mark = buf.create_mark(None, insert, True)
  311.                 self.end_mark = buf.create_mark(None, insert, False)
  312.                 
  313.                 # Now parse the contents of this snippet, create Placeholders
  314.                 # and insert the placholder marks in the marks array of plugin_data
  315.                 self._parse(plugin_data)
  316.                 
  317.                 # So now all of the snippet is in the buffer, we have all our 
  318.                 # placeholders right here, what's next, put all marks in the 
  319.                 # plugin_data.marks
  320.                 k = self.placeholders.keys()
  321.                 k.sort(reverse=True)
  322.                 
  323.                 plugin_data.placeholders.insert(last_index, self.placeholders[0])
  324.                 last_iter = self.placeholders[0].end_iter()
  325.                 
  326.                 for tabstop in k:
  327.                         if tabstop != -1 and tabstop != 0:
  328.                                 placeholder = self.placeholders[tabstop]
  329.                                 end_iter = placeholder.end_iter()
  330.                                 
  331.                                 if last_iter.compare(end_iter) < 0:
  332.                                         last_iter = end_iter
  333.                                 
  334.                                 # Inserting placeholder
  335.                                 plugin_data.placeholders.insert(last_index, placeholder)
  336.                 
  337.                 # Move end mark to last placeholder
  338.                 buf.move_mark(self.end_mark, last_iter)
  339.  
  340.                 return self
  341.                 
  342.         def deactivate(self):
  343.                 buf = self.begin_mark.get_buffer()
  344.                 
  345.                 buf.delete_mark(self.begin_mark)
  346.                 buf.delete_mark(self.end_mark)
  347.                 
  348.                 self.placeholders = {}
  349.         
  350.         def begin_iter(self):
  351.                 return self.begin_mark.get_buffer().get_iter_at_mark(self.begin_mark)
  352.         
  353.         def end_iter(self):
  354.                 return self.end_mark.get_buffer().get_iter_at_mark(self.end_mark)
  355. # ex:ts=8:et:
  356.